package pl.edu.pw.ee.buildcity.scheduler;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import pl.edu.pw.ee.buildcity.domain.BuildStatus;
import pl.edu.pw.ee.buildcity.entities.BuildActivity;
import pl.edu.pw.ee.buildcity.entities.BuildDefinition;
import pl.edu.pw.ee.buildcity.entities.SCMCommit;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Stores and delivers all necessary information about current build.
 *
 * @author Mateusz
 * @since 2010-02-28
 */
public class BuildContext {

	private static final Logger log = Logger.getLogger(BuildContext.class);

	private List<SCMCommit> changes = new ArrayList<SCMCommit>();

	private final String buildName;
	private final String urlToCheckout;
	private final String workingCopy;
	private final String buildCommand;
	private final boolean forceCleanBuildEnabled;
	private final Date fireTime;
	private Exception failReason;

	private BuildActivity buildActivity;

	public BuildContext(BuildDefinition buildDefinition) {
		this.fireTime = new Date();
		this.buildName = buildDefinition.getName();
		this.workingCopy = buildDefinition.getWorkingCopy();
		this.buildCommand = buildDefinition.getBuildCommand();
		this.urlToCheckout = buildDefinition.getRepositoryURL();
		this.forceCleanBuildEnabled = buildDefinition.isForceCleanBuild();
		log.info("Created new build context: " + this);
	}

	public void setChanges(List<SCMCommit> changes) {
		this.changes = changes;
	}

	public List<SCMCommit> getChanges() {
		return changes;
	}

	public String getUrlToCheckout() {
		return urlToCheckout;
	}

	public String getWorkingCopyLocation() {
		return workingCopy;
	}

	public String getBuildCommand() {
		return buildCommand;
	}

	public boolean isForceCleanBuildEnabled() {
		return forceCleanBuildEnabled;
	}

	public String getBuildName() {
		return buildName;
	}

	public Date getFireTime() {
		return fireTime;
	}

	public BuildStatus getResult() {
		return failReason == null ? BuildStatus.SUCCEEDED : BuildStatus.FAILED;
	}

	/**
	 * If given parameter is not null, build is considered as failed.
	 * When null, build is considered as successful.
	 *
	 * @param failReason exception which occurred during build. May be null.
	 */
	public void considerAsFailed(Exception failReason) {
		this.failReason = failReason;
	}

	public BuildActivity getBuildActivity() {
		return buildActivity;
	}

	public void setBuildActivity(BuildActivity buildActivity) {
		this.buildActivity = buildActivity;
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}
}